package middleware

import (
	"gitee.com/Luna-CY/hui-hui/internal/cache"
	"gitee.com/Luna-CY/hui-hui/internal/logger"
	"gitee.com/Luna-CY/hui-hui/internal/runtime"
	"gitee.com/Luna-CY/hui-hui/server/http/response"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"net/http"
	"strings"
)

func NewAuthentication() gin.HandlerFunc {
	var abort = func(c *gin.Context, code int, message string) {
		var v response.Response[any]
		v.Code = code
		v.Message = message

		c.JSON(http.StatusOK, v)
		c.Abort()
	}

	return func(c *gin.Context) {
		// 优先检查下载器的临时Token
		if token := c.Query("downloader-temporary-token"); "" != token {
			var v, err = cache.GetCache().Get(cache.AuthorizationTemporaryToken)
			if nil != err {
				abort(c, response.NeedAuthentication, "需要登录")

				return
			}

			// 短路判断
			if token == v {
				if err := cache.GetCache().Del(cache.AuthorizationTemporaryToken); nil != err {
					logger.GetLogger().Sugar().Errorf("删除缓存失败: %s", err)
				}
				c.Next()

				return
			}
		}

		// JWT鉴权
		var tokens = strings.Split(c.GetHeader("Authorization"), " ")
		if 2 != len(tokens) || "Bearer" != tokens[0] {
			abort(c, response.NeedAuthentication, "需要登录")

			return
		}

		token, err := jwt.ParseWithClaims(tokens[1], jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {
			return []byte(runtime.Uuid), nil
		})

		if nil != err || !token.Valid {
			abort(c, response.NeedAuthentication, "需要登录")

			return
		}

		claims, ok := token.Claims.(jwt.MapClaims)
		if !ok {
			abort(c, response.NeedAuthentication, "需要登录")

			return
		}

		secret, err := cache.GetCache().Get(cache.AuthorizationSecret)
		if nil != err {
			abort(c, response.Unknown, "内部错误")

			return
		}

		if v, ok := claims["secret"]; !ok || secret != v.(string) {
			abort(c, response.NeedAuthentication, "需要登录")

			return
		}

		c.Next()
	}
}
